#ifndef Kernel_MTRAModel_h
#define Kernel_MTRAModel_h

#include "Utility/Algebra/ODESystem.h"

#include "MModel.h"
namespace Kernel
{
    /**
     * @brief    模态法瞬态响应分析中，当阻尼阵未解耦时传递给直接法的模型
     * 
     * Model passed to the direct method in modal transient response analysis when the damping matrix is not decoupled.
     * 
     * @author   wjw
     * @date     2025.01.16
     */
    class KERNEL_EXPORT MTRAModel : public SG::Algebra::SecondOrderODESystem
    {
      public:
        explicit MTRAModel (Kernel::MModel myModel, const SG::Algebra::Mat_t& phi, const SG::Algebra::Vec_t& eigen);
        virtual ~MTRAModel ();

        void ComputeDerivatives (const SG::Algebra::Real_t& t,
                                 const SG::Algebra::Vec_t&  u,
                                 const SG::Algebra::Vec_t&  v,
                                 SG::Algebra::Vec_t&        a) override;
        void ComputeImplicitValue (const SG::Algebra::Real_t& t,
                                   const SG::Algebra::Vec_t&  u,
                                   const SG::Algebra::Vec_t&  v,
                                   const SG::Algebra::Vec_t&  a,
                                   SG::Algebra::Vec_t&        f) override;
        void ComputeExplicitValue (const SG::Algebra::Real_t& t,
                                   const SG::Algebra::Vec_t&  u,
                                   const SG::Algebra::Vec_t&  v,
                                   SG::Algebra::Vec_t&        g) override;
        void ComputeImplicitJacobian (const SG::Algebra::Real_t& t,
                                      const SG::Algebra::Vec_t&  u,
                                      const SG::Algebra::Vec_t&  v,
                                      const SG::Algebra::Vec_t&  a,
                                      SG::Algebra::SpMat_t&      dfdu,
                                      SG::Algebra::SpMat_t&      dfdv,
                                      SG::Algebra::SpMat_t&      dfda) override;
        void ComputeExplicitJacobian (const SG::Algebra::Real_t& t,
                                      const SG::Algebra::Vec_t&  u,
                                      const SG::Algebra::Vec_t&  v,
                                      SG::Algebra::SpMat_t&      dgdu,
                                      SG::Algebra::SpMat_t&      dgdv) override;
        // 添加重置缓存的方法
        void ResetJacobianCache ()
        {
            m_jacobian_computed = false;
        }

      protected:
        Kernel::MModel     m_myModel;
        SG::Algebra::Mat_t m_phi;
        SG::Algebra::Vec_t m_eigen;

        // 缓存的Jacobian矩阵
        SG::Algebra::SpMat_t m_cached_dfdu;
        SG::Algebra::SpMat_t m_cached_dfdv;
        SG::Algebra::SpMat_t m_cached_dfda;
        bool                 m_jacobian_computed;  // 标记是否已经计算过Jacobian
    };

}  // namespace Kernel

#endif  // Kernel_MTRAModel_h
